
// "Copyright [2021] <Copyright Xinchi Han>"

#ifndef _Mmu_H_
#define _Mmu_H_

#include <memory>

#include "inet/common/INETDefs.h"
#include "inet/common/IInterfaceRegistrationListener.h"
#include "inet/common/IProtocolRegistrationListener.h"
#include "inet/linklayer/common/Ieee802Ctrl.h"
#include "inet/node/inet/MmuManager.h"
#include "inet/node/inet/PfcInfoTag_m.h"
#include "inet/common/packet/Message.h"
#include "inet/linklayer/ethernet/EtherPhyFrame_m.h"
#include "inet/linklayer/ethernet/EtherMacBase.h"
#include "inet/common/IProtocolRegistrationListener.h"
#include "inet/common/ProtocolTag_m.h"



namespace inet {

class INET_API Mmu : public cSimpleModule, public IProtocolRegistrationListener, public IInterfaceRegistrationListener
{
  public:
    void CheckAndSendResume(int ind, const MacAddress& mac_address_arrival_gate);
    MmuManager* GetMmuManager() {
        return mmu_manager_.get();
    }

  protected:
    void initialize() override;
    virtual void handleMessage(cMessage *msg) override;

    virtual void handleRegisterService(const Protocol& protocol, cGate *out, ServicePrimitive servicePrimitive) override;
    virtual void handleRegisterProtocol(const Protocol& protocol, cGate *in, ServicePrimitive servicePrimitive) override;
    virtual void handleRegisterInterface(const InterfaceEntry &interface, cGate *out, cGate *in) override;

  private:
    // helper functions that obtain the bandwidth and link delay for each lowerLayerIn gate.
    int getBandwidth(int gate_idx) {
        // TODO(Hanxinchi): obtain real bandwidth from topology.
        return 100;
    }
    int getLinkDelay(int gate_idx) {
        // TODO(Hanxinchi): obtain real delay from topology.
        return 10;
    }
    void sendPause(int ind, const MacAddress& mac_address_arrival_gate, int pause_unit);
    void sendResume(int ind, const MacAddress& mac_address_arrival_gate);

    int pause_unit_ = 1000;
    int num_ports_;
    std::unique_ptr<MmuManager> mmu_manager_;
};

}  // namespace inet
#endif
